package com.yunquan.ohana.ui.photos

import android.Manifest
import android.annotation.SuppressLint
import android.content.Intent
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.PopupWindow
import androidx.activity.result.contract.ActivityResultContracts
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
// import com.tbruyelle.rxpermissions3.RxPermissions
import com.yunquan.ohana.BR
import com.yunquan.ohana.R
import com.yunquan.ohana.adapter.ModelRecyclerAdapter
import com.yunquan.ohana.adapter.ModelRecyclerAdapter.ModelBindViewListener
import com.yunquan.ohana.adapter.ModelViewHolder
import com.yunquan.ohana.base.ui.BaseActivity
import com.yunquan.ohana.databinding.ActivityPhotosBinding
import com.yunquan.ohana.dialog.LoadingDialog
import com.yunquan.ohana.dialog.TipDialog
import com.yunquan.ohana.entity.FramesEntity
import com.yunquan.ohana.entity.PhotoGroupEntity
import com.yunquan.ohana.entity.PhotoResultEntity
import com.yunquan.ohana.entity.PhotosEntity
import com.yunquan.ohana.ui.editPhoto.image.CropImageActivity
import com.yunquan.ohana.ui.editPhoto.video.CropVideoActivity
import com.yunquan.ohana.ui.photos.adapter.PhotosAdapter
import com.yunquan.ohana.ui.photos.dialog.CameraTypeDialog
import com.yunquan.ohana.ui.photos.item.PhotosItemViewModel
import com.yunquan.ohana.ui.photos.preview.PreviewActivity
import com.yunquan.ohana.utils.CameraUtils
import com.yunquan.ohana.utils.L
import com.yunquan.ohana.utils.MediaUtils
import com.yunquan.ohana.utils.StringUtils
import com.yunquan.ohana.utils.SystemUtils
import com.yunquan.ohana.utils.ToastUtils
import com.yunquan.ohana.utils.Utils
import com.google.gson.Gson

class PhotosActivity : BaseActivity<ActivityPhotosBinding, PhotosViewModel>() {

    // private lateinit var mRxPermissions: RxPermissions
    private var isPermission = false
    private var showDialog = false
    private var isLoading = false

    private var photoGroupDialog: PopupWindow? = null
    private var photoGroupAdapter: ModelRecyclerAdapter<PhotoGroupEntity>? = null

    private var mCameraResultType: Int? = null
    private var mCameraResultUri: Uri? = null

    private var mAuthDialog: TipDialog? = null

    // 申请相册读取权限的 launcher（多权限）
    private val mediaPermissionLauncher = registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { result ->
        val granted = result.values.all { it }
        isPermission = granted
        handlePermissionResult(granted, showDialog)
    }

    // 申请相机权限的 launcher（单权限）
    private val cameraPermissionLauncher = registerForActivityResult(ActivityResultContracts.RequestPermission()) { state ->
        if (state) {
            val dialog = CameraTypeDialog(this)
            dialog.setOnTypeListener { type ->
                val (resultUri, intent) = if (type == 1) {
                    CameraUtils.takePhoto(this)
                } else {
                    CameraUtils.recordVideo(this)
                }
                mCameraResultType = type
                mCameraResultUri = resultUri
                intent?.let { i ->
                    mCameraResult.launch(i)
                }
            }
            dialog.show()
        }
    }

    override fun initContentView(savedInstanceState: Bundle?): Int {
        return R.layout.activity_photos
    }

    override fun initVariableId(): Int {
        return BR.photosViewModel
    }

    override fun initParam() {
        super.initParam()
        window.statusBarColor = resources.getColor(R.color.white)
        window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
    }

    override fun initData(savedInstanceState: Bundle?) {
        super.initData(savedInstanceState)
        binding!!.adapter = PhotosAdapter()
        val bundle = intent.extras
        bundle?.let {
            val single = it.getBoolean("single", false)
            val type = it.getInt("type", 0)
            viewModel!!.showType.set(type)
            viewModel!!.isSingleSelect.set(single)
        }
        // mRxPermissions = RxPermissions(this)
        getMediaPermission()
    }

    override fun onResume() {
        super.onResume()
        if (!isPermission && !showDialog) {
            getMediaPermission()
        } else if (isPermission && showDialog) {
            mAuthDialog?.dismiss()
            mAuthDialog = null
        }
    }

    override fun initViewObservable() {
        super.initViewObservable()
        binding!!.layoutRefresh.setOnRefreshListener {
            if (isLoading || binding!!.layoutRefresh.isRefreshing) {
                return@setOnRefreshListener
            }
            L.i("下拉刷新")
            isLoading = true
            binding!!.layoutRefresh.isRefreshing = true
            viewModel!!.mPage = 0
            viewModel!!.loadAllAlbumData(this)
        }

        binding!!.rvPhotos.addOnScrollListener(object : RecyclerView.OnScrollListener() {
            override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
                super.onScrolled(recyclerView, dx, dy)
                val layoutManager = recyclerView.layoutManager as LinearLayoutManager
                val lastVisibleItemPosition = layoutManager.findLastVisibleItemPosition()
                val totalItemCount = layoutManager.itemCount
                if (!isLoading && lastVisibleItemPosition >= totalItemCount - 1) {
                    isLoading = true
                    L.i("上拉加载")
                    viewModel!!.mPage++
                    viewModel!!.loadAllAlbumData(this@PhotosActivity)
                }
            }
        })

        binding!!.btnNext.setOnClickListener {
            setResultFinish()
        }
        viewModel!!.ui.observe(this) {
            when (it) {
                0 -> {
                    binding!!.ivGroupSort.rotation = 180f
                    showAccountsDialog()
                }

                1 -> {
                    getCameraPermission()
                }

                2 -> {
                    viewModel!!.mCurrentItem?.let { item ->
                        val position = viewModel!!.items.indexOf(item)
                        val ids = viewModel!!.checkedList.keys.joinToString(",")
                        val dataJson = Gson().toJson(viewModel!!.items.subList(1, viewModel!!.items.size).map { e -> e.data }.toList())
                        val bundle = Bundle()
                        bundle.putString("ids", ids)
                        bundle.putInt("index", position)
                        bundle.putString("data", dataJson)
                        val intent = Intent(this@PhotosActivity, PreviewActivity::class.java)
                        intent.putExtras(bundle)
                        mPreviewResult.launch(intent)
                    }
                }

                3 -> {
                    L.i("停止加载")
                    binding!!.layoutRefresh.isRefreshing = false
                    isLoading = false
                    dismissLoading()
                }
            }
        }
    }

    // 移除 RxPermissions，使用 Activity Result API 申请多媒体读取权限
    private fun getMediaPermission() {
        val permissions: Array<String> = when {
            Build.VERSION.SDK_INT <= Build.VERSION_CODES.P -> arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE)
            Build.VERSION.SDK_INT == Build.VERSION_CODES.Q -> arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE)
            Build.VERSION.SDK_INT in (Build.VERSION_CODES.R..Build.VERSION_CODES.S_V2) -> arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE)
            else -> arrayOf(
                Manifest.permission.READ_MEDIA_IMAGES,
                Manifest.permission.READ_MEDIA_VIDEO,
                Manifest.permission.READ_MEDIA_AUDIO
            )
        }
        if (permissions.isNotEmpty()) {
            mediaPermissionLauncher.launch(permissions)
        } else {
            handlePermissionResult(true, showDialog)
        }
    }

    private fun handlePermissionResult(granted: Boolean, showDialog: Boolean) {
        if (granted) {
            dismissAuthDialogIfNeeded(showDialog)
            getAlbum()
        } else {
            showPermissionDialog()
        }
    }

    private fun dismissAuthDialogIfNeeded(showDialog: Boolean) {
        if (showDialog) {
            mAuthDialog?.dismiss()
            mAuthDialog = null
        }
    }

    @SuppressLint("CheckResult")
    private fun getCameraPermission() {
        cameraPermissionLauncher.launch(Manifest.permission.CAMERA)
    }

    /**
     * 获取本地相册
     */
    private fun getAlbum() {
        showLoading()
        viewModel!!.loadAllAlbumGroup(this)
        viewModel!!.loadAllAlbumData(this)
    }

    /**
     * 显示权限弹窗
     */
    private fun showPermissionDialog() {
        if (mAuthDialog != null) return
        mAuthDialog = TipDialog(this)
        mAuthDialog!!.setTitle(getString(R.string.not_permission))
        mAuthDialog!!.setMessage(getString(R.string.tip_not_read_external_storage_permission))
        mAuthDialog!!.setRightBtn(getString(R.string.go_settings))
        mAuthDialog!!.setOnDialogClickListener(object : TipDialog.OnDialogClickListener() {
            override fun onRightClick() {
                super.onRightClick()
                SystemUtils.goToAppSettings(this@PhotosActivity)
            }

            override fun onLeftClick() {
                super.onLeftClick()
                finish()
            }
        })
        mAuthDialog!!.setOnDismissListener {
            showDialog = false
            mAuthDialog = null
        }
        mAuthDialog!!.show()
        showDialog = true
    }

    /**
     * 显示分组弹窗
     */
    private fun showAccountsDialog() {
        if (photoGroupDialog?.isShowing == true || photoGroupDialog != null) {
            photoGroupDialog?.dismiss()
            photoGroupDialog = null
            return
        }
        if (viewModel!!.groupList.isEmpty()) {
            return
        }
        val view = LayoutInflater.from(this).inflate(R.layout.dialog_photos_group, null)
        val rvContent = view.findViewById<RecyclerView>(R.id.rv_photos_accounts)
        rvContent.layoutManager = LinearLayoutManager(this)
        photoGroupAdapter = ModelRecyclerAdapter(this, viewModel!!.groupList, R.layout.item_photos_group)
        rvContent.adapter = photoGroupAdapter
        photoGroupAdapter!!.setBindViewListener(object : ModelBindViewListener<PhotoGroupEntity> {
            override fun onBindView(holder: ModelViewHolder, item: PhotoGroupEntity, position: Int) {
                holder.setText(R.id.tv_name, item.name)
                    .setText(R.id.tv_count, "(${item.count})")
                holder.getItemView().setOnClickListener {
                    viewModel!!.groupName.set(item.name)
                    viewModel!!.mPage = 0
                    isLoading = true
                    viewModel!!.loadAllAlbumData(this@PhotosActivity)
                    photoGroupDialog?.dismiss()
                }
            }
        })

        if (photoGroupDialog != null) {
            photoGroupDialog!!.dismiss()
            photoGroupDialog = null
        }
        photoGroupDialog = PopupWindow(view, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
        photoGroupDialog!!.isOutsideTouchable = true
        photoGroupDialog!!.isFocusable = true
        photoGroupDialog!!.isTouchable = true
        photoGroupDialog!!.setBackgroundDrawable(ColorDrawable(Color.parseColor("#00000000")))
        val y: IntArray = intArrayOf(0, 0)
        binding!!.llGroupMove.getLocationInWindow(y)
        // 移除不存在的动画样式 MyDialogTopStyle，使用默认动画
        photoGroupDialog!!.showAsDropDown(binding!!.llGroupMove, 0, -y[1])

        photoGroupDialog!!.setOnDismissListener {
            binding!!.ivGroupSort.rotation = 0f
        }
    }

    private fun setCheckedPhotos(bundle: Bundle?) {
        bundle?.let {
            val ids = it.getString("ids")
            val index = it.getInt("index", 0)
            val isSet = it.getBoolean("isSet")
            if (!ids.isNullOrEmpty()) {
                viewModel!!.checkedList.clear()
                val idLongs = ids.split(",").mapNotNull { s -> s.toLongOrNull() }
                idLongs.forEach { id ->
                    val itemVM = viewModel!!.items.find { vm -> vm.data?.id == id }
                    itemVM?.data?.let { data -> viewModel!!.checkedList[id] = data }
                }
                viewModel!!.items.forEach { vm ->
                    vm.data?.let { d ->
                        vm.checkChange(viewModel!!.checkedList.containsKey(d.id!!))
                    }
                }
                binding!!.rvPhotos.adapter?.notifyDataSetChanged()
            }
            if (isSet) {
                binding!!.rvPhotos.scrollToPosition(index + 1)
            }
        }
    }

    private fun setResultFinish() {
        val selected: MutableList<PhotosEntity> = ArrayList()
        viewModel!!.checkedList.forEach { (_, data) ->
            selected.add(data)
        }
        val framesJson = intent.extras?.getString("frames")
        if (framesJson.isNullOrEmpty()) {
            // 无需裁剪，直接返回路径列表
            val result: MutableList<String> = ArrayList()
            for (photo in selected) {
                photo.path?.let { result.add(it) }
            }
            L.v("选择的文件->" + result.joinToString(","))
            val jsonData = Gson().toJson(result)
            val bundle = Bundle()
            bundle.putString("data", jsonData)
            val intent = Intent()
            intent.putExtras(bundle)
            setResult(RESULT_OK, intent)
            finish()
        } else {
            // 需要裁剪，进入裁剪流程
            val cropList = selected.map { p ->
                PhotoResultEntity(
                    id = p.id,
                    path = p.path,
                    content = null,
                    cropId = null,
                    cropPath = null,
                    thumbnail = p.thumbnail,
                    type = p.type,
                    group = p.group,
                    duration = p.duration,
                    dateTime = p.dateTime,
                    width = p.width,
                    height = p.height,
                    size = p.size
                )
            }
            val photosJson = Gson().toJson(cropList)
            val b = Bundle()
            b.putString("photos", photosJson)
            b.putString("frames", framesJson)
            val isVideo = cropList.firstOrNull()?.type?.contains("video") == true
            val i = if (isVideo) {
                Intent(this, CropVideoActivity::class.java)
            } else {
                Intent(this, CropImageActivity::class.java)
            }
            i.putExtras(b)
            mEditResult.launch(i)
        }
    }

    private fun getPhotoByUri() {
        if (mCameraResultUri == null) {
            return
        }
        val framesJson = intent.extras?.getString("frames")
        if (mCameraResultType == 1) {
            val bean = MediaUtils.getImageById(this, mCameraResultUri!!.lastPathSegment!!)
            if (bean != null) {
                if (framesJson.isNullOrEmpty()) {
                    // 无需裁剪，直接返回路径
                    val result = mutableListOf<String>()
                    val path = bean.path!!
                    result.add(path)
                    val jsonData = Gson().toJson(result)
                    val bundle = Bundle()
                    bundle.putString("data", jsonData)
                    val intent = Intent()
                    intent.putExtras(bundle)
                    setResult(RESULT_OK, intent)
                    finish()
                } else {
                    // 需裁剪，进入裁剪流程
                    val photos = mutableListOf(bean)
                    val photosJson = Gson().toJson(photos)
                    val b = Bundle()
                    b.putString("photos", photosJson)
                    b.putString("frames", framesJson)
                    val i = Intent(this, CropImageActivity::class.java)
                    i.putExtras(b)
                    mEditResult.launch(i)
                }
            }
        } else if (mCameraResultType == 2) {
            val bean = MediaUtils.getVideoById(this, mCameraResultUri!!.lastPathSegment!!)
            if (bean != null) {
                if (framesJson.isNullOrEmpty()) {
                    // 无需裁剪，直接返回路径
                    val result = mutableListOf<String>()
                    val path = bean.path!!
                    result.add(path)
                    val jsonData = Gson().toJson(result)
                    val bundle = Bundle()
                    bundle.putString("data", jsonData)
                    val intent = Intent()
                    intent.putExtras(bundle)
                    setResult(RESULT_OK, intent)
                    finish()
                } else {
                    // 需裁剪，进入裁剪流程
                    val photos = mutableListOf(bean)
                    val photosJson = Gson().toJson(photos)
                    val b = Bundle()
                    b.putString("photos", photosJson)
                    b.putString("frames", framesJson)
                    val i = Intent(this, CropVideoActivity::class.java)
                    i.putExtras(b)
                    mEditResult.launch(i)
                }
            }
        }
    }

    private val mCameraResult = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
        // 这里处理返回结果
        if (result.resultCode == RESULT_OK) {
            getPhotoByUri()
        }
    }

    private val mPreviewResult = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
        // 这里处理返回结果
        if (result.resultCode == PreviewActivity.RESULT_CODE) {
            val bundle = result.data?.extras
            setCheckedPhotos(bundle)
        } else if (result.resultCode == PreviewActivity.RESULT_EXIT_CODE) {
            val bundle = result.data?.extras
            setCheckedPhotos(bundle)
        }
    }

    private val mEditResult = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
        // 这里处理返回结果
        if (result.resultCode == EDIT_RESULT_CODE) {
            finish()
        }
    }

    companion object {
        const val EDIT_RESULT_CODE = 10003
    }
}